package com.linko.intelligent.sys.core.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.linko.intelligent.base.UserInfo;
import com.linko.intelligent.common.config.StringRedisOperator;
import com.linko.intelligent.common.util.UUIDUtil;
import com.linko.intelligent.common.util.UserContext;
import com.linko.intelligent.sys.core.mapper.UserMapper;
import com.linko.intelligent.sys.core.service.RoleService;
import com.linko.intelligent.sys.core.service.UserService;
import com.linko.intelligent.sys.pojo.dto.LoginDto;
import com.linko.intelligent.sys.pojo.dto.UserDto;
import com.linko.intelligent.sys.pojo.po.Role;
import com.linko.intelligent.sys.pojo.po.User;
import com.linko.intelligent.sys.pojo.query.RoleQuery;
import com.linko.intelligent.sys.pojo.query.UserQuery;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author yuan
 * @create 2024/3/15 11:42
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {


    @Autowired
    StringRedisOperator redisOperator;
    @Autowired
    Gson gson;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleService roleService;

    @Override
    public Long save(UserDto dto) {
        User po = new User();
        BeanUtils.copyProperties(dto, po);
        po.setCreatorId(UserContext.getUserId());
        po.setCreateTime(new Date());
        po.setDel(0L);
        save(po);
        return po.getId();
    }

    @Override
    public Boolean delete(Long id) {
        User po = new User();
        po.setId(id);
        po.setDel(1L);
        return updateById(po);
    }

    @Override
    public Boolean update(Long id, UserDto dto) {
        User po = new User();
        BeanUtils.copyProperties(dto, po);
        po.setId(id);
        return updateById(po);
    }

    @Override
    public UserInfo getDetail(Long id) {
        User po = getById(id);
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(po, userInfo);

        if (StringUtils.isNotBlank(po.getRoleIds())) {
            List<Long> roleIdList = Arrays.stream(po.getRoleIds().split(",")).filter(it -> StringUtils.isNotBlank(it))
                    .map(it -> Long.parseLong(it)).collect(Collectors.toList());
            RoleQuery roleQuery = new RoleQuery();
            roleQuery.setIds(roleIdList);

            List<Role> roles = roleService.queryList(roleQuery);
            List<String> roleNameList = roles.stream().map(it -> it.getName()).distinct().filter(it -> StringUtils.isNotBlank(it)).collect(Collectors.toList());
            List<String> webContentList = roles.stream().map(it -> it.getWebContent()).distinct().filter(it -> StringUtils.isNotBlank(it)).collect(Collectors.toList());
            List<String> appContentList = roles.stream().map(it -> it.getAppContent()).distinct().filter(it -> StringUtils.isNotBlank(it)).collect(Collectors.toList());
            userInfo.setRoles(roleNameList);
            userInfo.setRoleIds(roleIdList);
            userInfo.setWebContentList(webContentList);
            userInfo.setAppConterntList(appContentList);
        }
        return userInfo;
    }

    @Override
    public List<User> queryList(UserQuery query) {
        List<User> list = userMapper.selectLs(query);
        wrapRole(list);
        return list;
    }


    @Override
    public PageInfo<User> queryPage(UserQuery query) {
        PageInfo<User> pageInfo = PageHelper.startPage(query.getPn(), query.getPs()).doSelectPageInfo(
                () -> queryList(query)
        );
        return pageInfo;
    }

    @Override
    public UserInfo login(LoginDto loginDto) {
        if (loginDto == null) {
            throw new RuntimeException("数据不能为空");
        }
        if (StringUtils.isBlank(loginDto.getPhone()) || loginDto.getPhone().length() != 11) {
            throw new RuntimeException("手机号不合法");
        }
        if (StringUtils.isBlank(loginDto.getPassword())) {
            throw new RuntimeException("密码不合法");
        }
        UserQuery userQuery = new UserQuery();
        userQuery.setPhone(loginDto.getPhone());
        userQuery.setPassword(loginDto.getPassword());
        List<User> userList = queryList(userQuery);
        if (CollectionUtils.isEmpty(userList)) {
            throw new RuntimeException("手机号或密码不正确");
        }
        if (userList.size() > 1) {
            throw new RuntimeException("帐号异常");
        }
        User tarUser = userList.get(0);

        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(tarUser, userInfo);
        String token = UUIDUtil.no();
        userInfo.setToken(token);
        redisOperator.set(token, gson.toJson(userInfo), 30 * 24 * 60 * 60);

        if (StringUtils.isNotBlank(tarUser.getRoleIds())) {
            List<Long> roleIdList = Arrays.stream(tarUser.getRoleIds().split(",")).filter(it -> StringUtils.isNotBlank(it))
                    .map(it -> Long.parseLong(it)).collect(Collectors.toList());
            RoleQuery roleQuery = new RoleQuery();
            roleQuery.setIds(roleIdList);

            List<Role> roles = roleService.queryList(roleQuery);
            List<String> roleNameList = roles.stream().map(it -> it.getName()).distinct().filter(it -> StringUtils.isNotBlank(it)).collect(Collectors.toList());
            List<String> webContentList = roles.stream().map(it -> it.getWebContent()).distinct().filter(it -> StringUtils.isNotBlank(it)).collect(Collectors.toList());
            List<String> appContentList = roles.stream().map(it -> it.getAppContent()).distinct().filter(it -> StringUtils.isNotBlank(it)).collect(Collectors.toList());
            userInfo.setRoles(roleNameList);
            userInfo.setWebContentList(webContentList);
            userInfo.setAppConterntList(appContentList);
        }


        return userInfo;
    }

    @Override
    public Long findIdByName(List<User> all, String name) {
        if (StringUtils.isBlank(name)) {
            return null;
        }
        User tar = org.apache.commons.collections4.CollectionUtils.find(all, new Predicate<User>() {
            @Override
            public boolean evaluate(User entity) {
                if (entity != null && StringUtils.isNotBlank(entity.getName()) && entity.getName().equals(name)) {
                    return true;
                }
                return false;
            }
        });
        if (tar != null) {
            return tar.getId();
        } else {
            return null;
        }
    }

    private void wrapRole(List<User> userList) {
        if (CollectionUtils.isEmpty(userList)) {
            return;
        }
        RoleQuery roleQuery = new RoleQuery();
        List<Role> allRoleList = roleService.queryList(roleQuery);
        if (CollectionUtils.isEmpty(allRoleList)) {
            return;
        }
        for (User u : userList) {
            if (StringUtils.isBlank(u.getRoleIds())) {
                continue;
            }
            List<Long> roleIdList = Arrays.stream(u.getRoleIds().split(",")).filter(it -> StringUtils.isNotBlank(it))
                    .map(it -> Long.parseLong("" + it)).collect(Collectors.toList());
            List<Role> roleList = new ArrayList<>();
            for (Long roleId : roleIdList) {
                for (Role role : allRoleList) {
                    if (roleId != null && roleId.longValue() == role.getId().longValue()) {
                        roleList.add(role);
                    }
                }
            }
            u.setRoleList(roleList);
        }
    }

}
